export function arrayPolyFill() {
    if (typeof Array.prototype.from !== 'function') {
        Array.prototype.from = (function () {
            let toStr = Object.prototype.toString;
            let isCallable = function (fn) {
                return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
            };
            const toInteger = function (value) {
                let number = Number(value);
                if (isNaN(number)) {
                    return 0;
                }
                if (number === 0 || !isFinite(number)) {
                    return number;
                }
                return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
            };
            const maxSafeInteger = Math.pow(2, 53) - 1;
            const toLength = function (value) {
                let len = toInteger(value);
                return Math.min(Math.max(len, 0), maxSafeInteger);
            };
            return function from(arrayLike /*, mapFn, thisArg */ ) {
                const C = this;
                let items = Object(arrayLike);
                if (arrayLike === null) {
                    throw new TypeError('Array.from requires an array-like object - not null or undefined');
                }
                let mapFn = arguments.length > 1 ? arguments[1] : void undefined;
                let T;
                if (typeof mapFn !== 'undefined') {
                    if (!isCallable(mapFn)) {
                        throw new TypeError('Array.from: when provided, the second argument must be a function');
                    }
                    if (arguments.length > 2) {
                        T = arguments[2];
                    }
                }
                let len = toLength(items.length), A = isCallable(C) ? Object(new C(len)) : new Array(len), k = 0, kValue;
                while (k < len) {
                    kValue = items[k];
                    if (mapFn) {
                        A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
                    } else {
                        A[k] = kValue;
                    }
                    k += 1;
                }
                A.length = len;
                return A;
            };
        }());
    }

    if (typeof Array.prototype.forEach !== 'function') {
        Array.prototype.forEach = function (callback, thisObj) {
            let T, k;
            if (this === null) {
                throw new TypeError(' this is null or not defined');
            }
            let O = Object(this), len = O.length >>> 0;
            if (typeof callback !== "function") {
                throw new TypeError(callback + ' is not a function');
            }
            if (arguments.length > 1) {
                T = thisObj;
            }
            k = 0;
            while (k < len) {
                let kValue;
                if (k in O) {
                    kValue = O[k];
                    callback.call(T, kValue, k, O);
                }
                k++;
            }
        };
    }
    //修正NodeList
    if(typeof NodeList.prototype.forEach !== 'function') {
        NodeList.prototype.forEach = Array.prototype.forEach;
    }

    if (typeof Array.prototype.each !== 'function') {
        Array.prototype.each = function (callback, thisObj) {
            let T, k;

            if (this === null) {
                throw new TypeError(' this is null or not defined');
            }
            let O = Object(this), len = O.length >>> 0;
            if (typeof callback !== "function") {
                throw new TypeError(callback + ' is not a function');
            }
            if (arguments.length > 1) {
                T = thisObj;
            }
            k = 0;
            while (k < len) {
                let kValue;
                if (k in O) {
                    kValue = O[k];
                    callback.call(T, kValue, k, O);
                }
                k++;
            }
        };
    }

    if (typeof Array.prototype.isArray !== 'function') {
        Array.prototype.isArray = function (arg) {
            return Object.prototype.toString.call(arg) === '[object Array]';
        }
    }

    if (typeof Array.prototype.includes !== 'function') {
        Array.prototype.includes = function (searchElement, fromIndex) {
            'use strict';
            if (this === null) {
                throw new TypeError('"this" is null or not defined');
            }
            let o = Object(this), len = o.length >>> 0;
            if (len === 0) {
                return false;
            }
            const n = fromIndex | 0;
            let k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
            while (k < len) {
                if (o[k] === searchElement) {
                    return true;
                }
                k++;
            }
            return false;
        }
    }

    if (typeof Array.prototype.find !== 'function') {
        Array.prototype.find = function (predicate) {
            'use strict';
            if (this === null) {
                throw new TypeError('Array.prototype.find called on null or undefined');
            }
            if (typeof predicate !== 'function') {
                throw new TypeError('predicate must be a function');
            }
            let list = Object(this), length = list.length >>> 0, thisArg = arguments[1], value;

            for (let i = 0; i < length; i++) {
                value = list[i];
                if (predicate.call(thisArg, value, i, list)) {
                    return value;
                }
            }
            return undefined;
        };
    }

    if (typeof Array.prototype.findIndex !== 'function') {
        Array.prototype.findIndex = function (predicate) {
            if (this === null) {
                throw new TypeError('Array.prototype.findIndex called on null or undefined');
            }
            if (typeof predicate !== 'function') {
                throw new TypeError('predicate must be a function');
            }
            let list = Object(this), length = list.length >>> 0, thisArg = arguments[1], value;

            for (let i = 0; i < length; i++) {
                value = list[i];
                if (predicate.call(thisArg, value, i, list)) {
                    return i;
                }
            }
            return -1;
        };
    }

    if(typeof Array.prototype.compact !== 'function') {
        Array.prototype.compact = function () {
            let index = -1, length = this === null ? 0 : this.length, resIndex = 0, result = [];
            while (++index < length) {
                let value = this[index];
                if(value) {
                    result[resIndex++] = value;
                }
            }
            return result;
        }
    }

    if(typeof Array.prototype.insertOf !== 'function') {
        Array.prototype.insertOf = function (index, value) {
            if(this.length < index) {
                throw Error('index can not big than length!');
            }
            this.splice(index, 0, value);
        }
    }
}